package org.slusk.thynwor.corestructures;

import java.awt.Color;
import java.awt.Component;

import javax.swing.JLabel;

import org.slusk.thynwor.corestructures.Drone.SignalType;
import org.slusk.thynwor.corestructures.Region.RegionType;
import org.slusk.thynwor.util.Coordinates;
import org.slusk.thynwor.util.Direction;
import org.slusk.thynwor.util.ThynworException;

public class Food extends Resource {
	
	private boolean isBeingTowed;
	private long leadTowerId;
	private int weight;
	private int effortApplied;
	
	public Food(Environment env, Coordinates coords) {
		super(env, coords);
		this.isBeingTowed = false;
		this.leadTowerId = -1;
		this.weight = Integer.parseInt(config.getProperty("Food.weight"));
		this.effortApplied = 0;
	}

	@Override
	public void doTurnActions() {
		// Check if at base; if so, die
		if (map.isInRegion(coords, RegionType.BASE)) {
//			if (!isBeingTowed)
//				throw new RuntimeException("A Food was collected that was not towed.");
			clearInteractingAgents();
			this.isBeingTowed = false;
			this.leadTowerId = -1;
			environment.incrementFoodCollected();
			environment.setEntityAsDead(this);
		}
	}
	
	public void die() {
		clearInteractingAgents();
		this.isBeingTowed = false;
		this.leadTowerId = -1;
		environment.incrementFoodCollected();
		environment.setEntityAsDead(this);
	}

	@Override
	public Entity clone() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public char getDisplayCharacter() {return '@';}

	@Override
	public EntityType getEntityType() {return EntityType.RESOURCE;}

	@Override
	public void move() {}

	@Override
	public void move(Direction direction) {
		Coordinates proposedCoordinates = GridMap.directionToCoordinates(direction, coords);
		try {
			map.moveEntityTo(this, proposedCoordinates);
			coords = proposedCoordinates;
			if (environment.isSingleAgentTowMode()) {
				for (IWorker agent : interactingAgent) {
					Entity e = (Entity) agent;
					if (e.getId() != leadTowerId) {
						e.move(direction);
						agent.setIsBeingTowed(true);
					}
				}
			}
		} catch (ThynworException e) {
			// Do nothing
		}
	}

	@Override
	public void addInteractingAgent(IWorker agent) {
		if (!interactingAgent.contains(agent)) {
			interactingAgent.add(agent);
			setEffortApplied(effortApplied + agent.getStrength());
		}	
	}
	
	@Override
	public void removeInteractingAgent(IWorker agent) {
		if(interactingAgent.remove(agent)) {
			setEffortApplied(effortApplied - agent.getStrength());
		}
		
		if (((Entity)agent).getId() == getLeadTowerId()) setLeadTowerId(-1);
	}
	
	private void setEffortApplied(int value) {
		effortApplied = value;
		if (effortApplied >= weight) {
			setIsBeingTowed(true);
			setSignal(null);
		} else {
			setIsBeingTowed(false);
			if (effortApplied > 0) setSignal(SignalType.ASSISTFOOD);
			else  setSignal(null);
		}
	}
	
	@Override
	public void clearInteractingAgents() {
		for (IWorker agent : interactingAgent) {
			agent.forceDisengage();
		}
		interactingAgent.clear();
		setEffortApplied(0);
		setLeadTowerId(-1);
	}
	
	@Override
	public void render(Component cell) {
		((JLabel)cell).setText(this.getDisplayCharacter()+"");
		
		if (!isEngaged()){
			cell.setBackground(new Color(100, 255, 150));
		} else if (isEngaged() && !isBeingTowed) {
			cell.setBackground(new Color(200, 155, 100));
		} else {
			cell.setBackground(new Color(200, 255, 250));
		}
		
		((JLabel)cell).setIcon(null);
	}

	@Override
	public boolean isTowable() {return true;}
	@Override
	public int getNumRequiredForTowing() {return 2;}
	@Override
	public boolean isBeingTowed() {return isBeingTowed;}
	@Override
	public void setIsBeingTowed(boolean flag) {
		isBeingTowed = flag;
		for (IWorker worker : getInteractingAgents()) {
			worker.setIsTowing(flag);
		}
	}
	
	public int getWeight() {return weight;}
	public long getLeadTowerId() {return leadTowerId;}
	public void setLeadTowerId(long id) {this.leadTowerId = id;}

	public String getInfo() {
		StringBuilder sb = new StringBuilder();
		sb.append(super.getInfo());
		sb.append("IsAvailable? ");
		sb.append(isAvailable());
		sb.append("\nIs Being Towed? ");
		sb.append(isBeingTowed);
		sb.append("\nLeadTowerId: ");
		sb.append(leadTowerId);
		sb.append("\nInteracting Agents:\n");
		for (IWorker worker : interactingAgent) {
			sb.append(worker.getClass().getSimpleName());
			sb.append(" (");
			Entity e = (Entity) worker;
			sb.append(e.getId());
			sb.append("): ");
			sb.append(e.getCoordinates());
			sb.append("\n");
		}
		
		
		return sb.toString();
	}

}
